﻿using System;
using System.Text;
using Google.Protobuf;

namespace GSE.Rpc
{
    public class Request : RpcObject
    {
        protected string serviceName;

        public Request(string serviceName, UInt16 transactionID, IMessage param)
        {
            this.transactionID = transactionID;
            this.param = param;
            this.serviceName = serviceName;
        }

        public string GetServiceName()
        {
            return serviceName;
        }
        /// <summary>
        ///
        ///
        /// </summary>
        /// <param name="serviceName"></param>
        /// <param name="transactionID"></param>
        /// <param name="param">protobuf Message 序列化数据</param>
        public Request(string serviceName, UInt16 transactionID, byte[] param)
        {
            this.transactionID = transactionID;
            dataBytes = param;
            this.serviceName = serviceName;
        }

        public override byte[] Encode()
        {
            var mb = param != null ? param.ToByteArray() : dataBytes;

            var sb = Encoding.UTF8.GetBytes(serviceName);
            // verNo + packet length + transaction id + service name length + service name + message data
            var data = new byte[1 + 4 + 2 + 1 + sb.Length + mb.Length];
            var offset = 0;
            data[offset] = protoVerNo << 3 + (byte)LogicPacketType.RPC;
            offset += 1;
            // -5, 去除固定头部的verNo和包长度.
            var dataLengthB = BitConverter.GetBytes((UInt32)(data.Length - 5));
            Array.Reverse(dataLengthB);
            Array.Copy(dataLengthB, 0, data, offset, 4);
            offset += 4;
            // transaction id

            var transactionIdB = BitConverter.GetBytes(transactionID);
            Array.Reverse(transactionIdB);
            Array.Copy(transactionIdB, 0, data, offset, 2);
            offset += 2;
            // service name 长度段.
            var serviceNameLengthB = BitConverter.GetBytes((byte)sb.Length);
            Array.Copy(serviceNameLengthB, 0, data, offset, 1);
            offset += 1;
            // service name 段.
            Array.Copy(sb, 0, data, offset, sb.Length);
            offset += sb.Length;

            // 参数内容段.
            Array.Copy(mb, 0, data, offset, mb.Length);
            return data;
        }
    }
}
